#界面相关工具函数，如创建菜单、布局等
import tkinter as tk
from tkinter import ttk, font
from PIL import Image, ImageTk

def setup_styles(app):
    """设置界面样式"""
    try:
        app.default_font = font.Font(family="SimHei", size=10)
        app.menu_font = font.Font(family="SimHei", size=10, weight="bold")
    except:
        app.default_font = font.Font(family="Arial", size=10)
        app.menu_font = font.Font(family="Arial", size=10, weight="bold")

    app.option_add("*Font", app.default_font)

    app.bg_color = "#f0f0f0"
    app.menu_bg = "#e0e0f0"
    app.menu_hover_bg = "#c0c0e0"
    app.frame_bg = "#ffffff"
    app.border_color = "#a0a0a0"

    app.configure(bg=app.bg_color)

def create_menu(app, shared_data):
    """创建菜单栏和子菜单"""
    app.menubar = tk.Menu(app, bg=app.menu_bg, relief=tk.FLAT)

    # 文件菜单
    app.file_menu = tk.Menu(app.menubar, tearoff=0, bg=app.frame_bg)
    app.file_menu.add_command(label="打开文件夹", command=app.cmd_open_folder)
    app.file_menu.add_command(label="打开图片", command=app.cmd_open_image)
    app.file_menu.add_command(label="打开视频", command=app.cmd_open_video)
    app.file_menu.add_command(label="打开摄像头", command=app.cmd_open_camera)
    app.file_menu.add_separator()
    app.recent_files_menu = tk.Menu(app, tearoff=0, bg="#ffffff")
    app.file_menu.add_cascade(label="最近文件", menu=app.recent_files_menu)
    app.file_menu.add_separator()
    app.file_menu.add_command(label="保存结果", command=app.cmd_save_result)
    app.file_menu.add_command(
    label="删除",
    command=app.cmd_delete_selected_file,
    )
    app.file_menu.add_command(label="批量检测", command=app.cmd_batch_detect)
    app.file_menu.add_separator()
    app.file_menu.add_command(label="退出", command=app.quit_application)

    # 模型菜单
    app.model_menu = tk.Menu(app.menubar, tearoff=0, bg=app.frame_bg)
    app.model_menu.add_command(label="加载模型", command=app.cmd_load_model)
    app.model_menu.add_command(label="模型库", command=app.cmd_model_library)
    app.model_menu.add_command(label="模型参数", command=app.cmd_model_params)

    # 数据菜单
    app.data_menu = tk.Menu(app.menubar, tearoff=0, bg=app.frame_bg)
    app.data_menu.add_command(label="加载 data.yaml", command=app.cmd_load_data)

    # 训练菜单
    app.train_menu = tk.Menu(app.menubar, tearoff=0, bg=app.frame_bg)
    app.train_menu.add_command(label="调整参数", command=app.cmd_train_params)
    app.train_menu.add_separator()
    app.train_menu.add_command(label="开始", command=app.cmd_train_start)
    app.train_menu.add_command(label="暂停", command=app.cmd_train_pause)
    app.train_menu.add_command(label="停止", command=app.cmd_train_stop)

    # 推理菜单
    app.infer_menu = tk.Menu(app.menubar, tearoff=0, bg=app.frame_bg)
    app.infer_menu.add_command(label="调整参数", command=app.cmd_infer_params)
    app.infer_menu.add_separator()
    app.infer_menu.add_command(label="开始", command=app.cmd_infer_start)
    app.infer_menu.add_command(label="暂停", command=app.cmd_infer_pause)
    app.infer_menu.add_command(label="停止", command=app.cmd_infer_stop)

    # 关于菜单
    app.about_menu = tk.Menu(app.menubar, tearoff=0, bg=app.frame_bg)
    app.about_menu.add_command(label="关于软件", command=app.cmd_about)
    app.about_menu.add_command(label="帮助文档", command=app.cmd_help)


    # 将菜单添加到菜单栏
    app.menubar.add_cascade(label="文件", menu=app.file_menu)
    app.menubar.add_cascade(label="模型", menu=app.model_menu)
    app.menubar.add_cascade(label="数据", menu=app.data_menu)
    app.menubar.add_cascade(label="训练", menu=app.train_menu)
    app.menubar.add_cascade(label="推理", menu=app.infer_menu)
    app.menubar.add_cascade(label="关于", menu=app.about_menu)

    app.config(menu=app.menubar)

def create_main_interface(app, shared_data):
    """创建主界面布局"""
    main_container = ttk.Frame(app, padding="10")
    main_container.pack(fill=tk.BOTH, expand=True)

    # 左侧面板容器
    left_panel = ttk.Frame(main_container)
    left_panel.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))

    # 文件列表
    app.file_list_container = ttk.LabelFrame(left_panel, text="文件列表", padding="10")
    app.file_list_container.pack(side=tk.TOP, fill=tk.Y, expand=False)

    app.file_listbox = tk.Listbox(
        app.file_list_container,
        width=25,
        height=10,
        selectmode=tk.EXTENDED,
        font=app.default_font,
        bg="white",
        relief=tk.SOLID,
        borderwidth=1
    )
    app.file_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    

    scrollbar = ttk.Scrollbar(app.file_list_container, orient=tk.VERTICAL, command=app.file_listbox.yview)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    app.file_listbox.config(yscrollcommand=scrollbar.set)

    # 绑定事件
    app.file_listbox.bind("<<ListboxSelect>>", app.on_file_select)
    app.file_listbox.bind("<Up>", app.on_key_up)
    app.file_listbox.bind("<Down>", app.on_key_down)
    app.file_listbox.bind("<Delete>", lambda event: app.cmd_delete_selected_file())

    # 预测结果文件列表
    app.pred_list_container = ttk.LabelFrame(left_panel, text="预测结果文件列表", padding="10")
    app.pred_list_container.pack(side=tk.TOP, fill=tk.Y, expand=False, pady=(10, 0))

    app.pred_listbox = tk.Listbox(
        app.pred_list_container,
        width=25,
        height=8,
        selectmode=tk.SINGLE,
        font=app.default_font,
        bg="white",
        relief=tk.SOLID,
        borderwidth=1
    )
    app.pred_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    pred_scrollbar = ttk.Scrollbar(app.pred_list_container, orient=tk.VERTICAL, command=app.pred_listbox.yview)
    pred_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    app.pred_listbox.config(yscrollcommand=pred_scrollbar.set)

    # 绑定事件
    app.pred_listbox.bind("<<ListboxSelect>>", app.on_pred_file_select)
    app.pred_listbox.bind("<Up>", app.on_pred_key_up)
    app.pred_listbox.bind("<Down>", app.on_pred_key_down)

    # 模型配置区
    app.model_config_container = ttk.LabelFrame(left_panel, text="模型配置", padding="10")
    app.model_config_container.pack(side=tk.TOP, fill=tk.X, expand=False, pady=(10, 0))

    # 模型版本选择
    ttk.Label(app.model_config_container, text="模型版本:").pack(anchor=tk.W, pady=(5, 2))
    app.model_version = tk.StringVar(value=shared_data.model_config["version"])
    app.version_combobox = ttk.Combobox(
        app.model_config_container,
        textvariable=app.model_version,
        values=list(shared_data.pretrained_models.keys()),
        state="readonly",
        width=22
    )
    app.version_combobox.pack(anchor=tk.W, pady=(0, 5))
    app.version_combobox.bind("<<ComboboxSelected>>", app.on_model_version_change)

    # 模型权重选择
    ttk.Label(app.model_config_container, text="模型权重:").pack(anchor=tk.W, pady=(5, 2))
    app.model_weight = tk.StringVar(value="")
    app.weight_combobox = ttk.Combobox(
        app.model_config_container,
        textvariable=app.model_weight,
        state="readonly",
        width=22
    )
    app.weight_combobox.pack(anchor=tk.W, pady=(0, 5))
    app.weight_combobox.bind("<<ComboboxSelected>>", app.on_model_weight_change)

    # 置信度阈值
    ttk.Label(app.model_config_container, text="置信度阈值:").pack(anchor=tk.W, pady=(5, 2))
    app.confidence_scale = ttk.Scale(
        app.model_config_container,
        from_=0.1,
        to=1.0,
        orient=tk.HORIZONTAL,
        length=200,
        value=shared_data.model_config["confidence"],
        command=lambda v: app.update_scale_label(v, app.confidence_label)
    )
    app.confidence_scale.pack(anchor=tk.W, pady=(0, 2))
    app.confidence_label = ttk.Label(
        app.model_config_container,
        text=f"{shared_data.model_config['confidence']:.1f}"
    )
    app.confidence_label.pack(anchor=tk.W, pady=(0, 5))

    # IOU阈值
    ttk.Label(app.model_config_container, text="IOU阈值:").pack(anchor=tk.W, pady=(5, 2))
    app.iou_scale = ttk.Scale(
        app.model_config_container,
        from_=0.1,
        to=1.0,
        orient=tk.HORIZONTAL,
        length=200,
        value=shared_data.model_config["iou"],
        command=lambda v: app.update_scale_label(v, app.iou_label)
    )
    app.iou_scale.pack(anchor=tk.W, pady=(0, 2))
    app.iou_label = ttk.Label(
        app.model_config_container,
        text=f"{shared_data.model_config['iou']:.1f}"
    )
    app.iou_label.pack(anchor=tk.W, pady=(0, 5))

    # 初始化模型权重下拉框
    update_weight_combobox(app, shared_data)

    # 中间：源文件展示区域
    app.source_frame = ttk.LabelFrame(main_container, text="源文件展示", padding="10")
    app.source_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))

    app.source_canvas = tk.Canvas(app.source_frame, bg="white", highlightthickness=1, highlightbackground="#ccc")
    app.source_canvas.pack(fill=tk.BOTH, expand=True)

    # 初始化占位提示
    app.source_canvas.create_text(
        0, 0,
        text="源文件展示",
        fill="gray",
        font=("SimHei", 12) if "SimHei" in font.families() else ("Arial", 12),
        tags="placeholder",
        anchor="center"
    )
    app.source_canvas.bind("<Configure>", app.update_source_placeholder_position)
    app.source_canvas.bind("<Button-1>", app.toggle_video_play)

    # 新增：关闭摄像头按钮（初始隐藏）
    app.stop_camera_btn = ttk.Button(
    app.source_frame,
    text="关闭摄像头",
    command=app.stop_camera_and_hide_button  # ✅ 改为 app 的方法
    )
    app.stop_camera_btn.pack(pady=5)
    app.stop_camera_btn.pack_forget()  # 初始隐藏

    # 右侧：预测结果展示区域
    app.result_frame = ttk.LabelFrame(main_container, text="预测结果文件展示", padding="10")
    app.result_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(10, 0))

    app.result_canvas = tk.Canvas(app.result_frame, bg="white", highlightthickness=1, highlightbackground="#ccc")
    app.result_canvas.pack(fill=tk.BOTH, expand=True)

    # 初始化占位提示
    app.result_canvas.create_text(
        0, 0,
        text="预测结果文件展示",
        fill="gray",
        font=("SimHei", 12) if "SimHei" in font.families() else ("Arial", 12),
        tags="placeholder",
        anchor="center"
    )
    app.result_canvas.bind("<Configure>", app.update_result_placeholder_position)

    # 更新共享数据中的UI元素引用
    shared_data.ui_elements.update({
        "file_listbox": app.file_listbox,
        "pred_listbox": app.pred_listbox,
        "source_canvas": app.source_canvas,
        "result_canvas": app.result_canvas,
        "version_combobox": app.version_combobox,
        "weight_combobox": app.weight_combobox,
        "confidence_scale": app.confidence_scale,
        "confidence_label": app.confidence_label,
        "iou_scale": app.iou_scale,
        "iou_label": app.iou_label
    })

def update_weight_combobox(app, shared_data):
    """更新权重下拉框内容"""
    version = app.model_version.get()
    weights = shared_data.pretrained_models.get(version, [])
    app.weight_combobox['values'] = weights
    if weights:
        app.weight_combobox.current(0)
        shared_data.model_config["weight_path"] = weights[0]

def display_image_on_canvas(pil_image, canvas):
    """将 PIL 图像缩放并显示在指定 Canvas 上"""
    canvas.delete("placeholder")

    canvas_width = canvas.winfo_width()
    canvas_height = canvas.winfo_height()

    if canvas_width <= 1:
        canvas_width = 600
    if canvas_height <= 1:
        canvas_height = 400

    img_width, img_height = pil_image.size
    scale = min(canvas_width / img_width, canvas_height / img_height)
    new_width = int(img_width * scale)
    new_height = int(img_height * scale)

    resized_image = pil_image.resize((new_width, new_height), Image.LANCZOS)
    tk_image = ImageTk.PhotoImage(resized_image)

    x = (canvas_width - new_width) // 2
    y = (canvas_height - new_height) // 2

    canvas.delete("all")
    canvas.create_image(x, y, anchor=tk.NW, image=tk_image)
    canvas.image = tk_image